package Grafico;

import Objetos.*;
import java.util.*;
import java.io.*;
import Mundo.*;
import Personajes.*;
import Interfaz.*;
import IA.*;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.swing.JFileChooser;
import javax.swing.JOptionPane;
import javax.swing.filechooser.FileNameExtensionFilter;
import javax.imageio.*;
import java.awt.image.*;

public class Juego implements Serializable {

    transient private ArrayList<BufferedImage> tiles;
    transient private ArrayList<BufferedImage> sprites;
    private ArrayList<Ejercito> ejercitos = new ArrayList();
    public Batallon batallon_activo;

    public ArrayList<Ejercito> getEjercitos() {
        return ejercitos;
    }
    private GestorMapas gestorMapas;
    private ArrayList<Aldea> aldeas = new ArrayList();
    transient Ventana_principal v;

    public void setDib(Dibujador dib) {
        this.dib = dib;
    }

    public void set_batallon(Batallon bata) {
        batallon_activo = bata;

    }

    public Batallon get_batallon() {

        return this.batallon_activo;
    }

    public Ventana_principal getv() {
        return v;
    }

    public void setV(Ventana_principal v) {
        this.v = v;
    }
    transient Dibujador dib;

    public Dibujador getDib() {
        return dib;
    }
    Mapa map;
    transient ArrayList<Objetivo> objetivos;
    transient IA ia;

    public ArrayList<BufferedImage> getTiles() {
        return tiles;
    }

    public ArrayList<Objetivo> getobjetivos() {

        return this.objetivos;
    }

    public IA getIa() {
        return ia;
    }

    public void setia(IA ia) {

        this.ia = ia;

    }
    transient Armeria arm;

    public void cargaTiles() throws IOException {
        tiles = new ArrayList();
        tiles.add(ImageIO.read(new File("camino.png")));
        tiles.add(ImageIO.read(new File("cerro.png")));
        tiles.add(ImageIO.read(new File("techo.png")));
        tiles.add(ImageIO.read(new File("pared.png")));
        tiles.add(ImageIO.read(new File("escalera.png")));
        tiles.add(ImageIO.read(new File("muroMuni.png")));
        tiles.add(ImageIO.read(new File("pisoMuni.png")));
    }

    public void cargaSprites() throws IOException {
        // se agrega uno por tipo de personaje
        sprites = new ArrayList();
        sprites.add(ImageIO.read(new File("angulo.png")));//0
        sprites.add(ImageIO.read(new File("rabonaPatriota.png")));//1
        sprites.add(ImageIO.read(new File("soldadoPatriota.png")));//2
        sprites.add(ImageIO.read(new File("aldeanoPatriota.png")));//3
        sprites.add(ImageIO.read(new File("aldeanoPatriota.png")));//4
        sprites.add(ImageIO.read(new File("soldadoPatriota.png")));//5
        sprites.add(ImageIO.read(new File("soldadoPatriota.png")));//6
        sprites.add(ImageIO.read(new File("soldadoPatriota.png")));//7
        sprites.add(ImageIO.read(new File("soldadoPatriota.png")));//8

        sprites.add(ImageIO.read(new File("angulo.png")));
        sprites.add(ImageIO.read(new File("rabonaRealista.png")));
        sprites.add(ImageIO.read(new File("soldadoRealista.png")));
        sprites.add(ImageIO.read(new File("aldeanoRealista.png")));
        sprites.add(ImageIO.read(new File("aldeanoRealista.png")));
        sprites.add(ImageIO.read(new File("soldadoRealista.png")));
        sprites.add(ImageIO.read(new File("soldadoRealista.png")));
        sprites.add(ImageIO.read(new File("soldadoRealista.png")));
        sprites.add(ImageIO.read(new File("soldadoRealista.png")));

        sprites.add(ImageIO.read(new File("angulo.png")));
        sprites.add(ImageIO.read(new File("rabonaIndigena.png")));
        sprites.add(ImageIO.read(new File("soldadoIndigena.png")));
        sprites.add(ImageIO.read(new File("aldeanoIndigena.png")));
        sprites.add(ImageIO.read(new File("aldeanoIndigena.png")));
        sprites.add(ImageIO.read(new File("soldadoIndigena.png")));
        sprites.add(ImageIO.read(new File("soldadoIndigena.png")));
        sprites.add(ImageIO.read(new File("soldadoIndigena.png")));
        sprites.add(ImageIO.read(new File("soldadoIndigena.png")));
        Batallon.sprites = sprites;
    }

    public void cargarAldeas() throws FileNotFoundException {
        File posini = new File("posiniAldeas.txt");
        Scanner sc = new Scanner(posini);
        int numAld = sc.nextInt();//el numero de aldeas en el archivo
        Mapa map = gestorMapas.getmapa("La Toma de Cuzco");
        for (int i = 0; i < numAld; i++) {
            int posx = sc.nextInt();
            int posy = sc.nextInt();
            int a = sc.nextInt();
            int b = sc.nextInt();
            Aldea ald = new Aldea(posx, posy, a, b, map);
            for (int j = 0; j < 9; j++) {
                int cant = sc.nextInt();
                for (int k = 0; k < cant; k++) {
                    switch (j) {
                        case 0:
                            ald.getAldeanos().add(new Heroe());
                            break;
                        case 1:
                            ald.getAldeanos().add(new Rabona());
                            break;
                        case 2:
                            ald.getAldeanos().add(new ArtilleriaRealista());
                            break;
                        case 3:
                            ald.getAldeanos().add(new MeleePeru());
                            break;
                        case 4:
                            ald.getAldeanos().add(new RangoPeru());
                            break;
                        case 5:
                            ald.getAldeanos().add(new MeleeRealista());
                            break;
                        case 6:
                            ald.getAldeanos().add(new RangoRealista());
                            break;
                        case 7:
                            ald.getAldeanos().add(new EspecialMeleeRealista());
                            break;
                        case 8:
                            ald.getAldeanos().add(new EspecialRangoRealista());
                            break;
                    }
                }
            }
            for (int j = 0; j < 9; j++) {
                int cant = sc.nextInt();
                for (int k = 0; k < cant; k++) {
                    ald.getArmas().add(j);
                }
            }
            aldeas.add(ald);
        }
    }

    public void cargarEjercitos(ArrayList<Ejercito> ejercitos) throws FileNotFoundException {
        File posini = new File("posini.txt");
        Scanner sc = new Scanner(posini);
        sc.nextLine();
        sc.nextLine();
        sc.nextLine();
        sc.nextLine();
        int numBat = sc.nextInt();//el numero de batallones en el archivo
        Ejercito patriotas = new Ejercito();
        Ejercito realistas = new Ejercito();
        Ejercito others = new Ejercito();
        Mapa map = gestorMapas.getmapa("La Toma de Cuzco");
        for (int i = 0; i < numBat; i++) {
            int bando = sc.nextInt();//para saber si es batallon patriota o realista
            int posx = sc.nextInt();//leemos la psoicion de los batallones
            int posy = sc.nextInt();
            Batallon bat = new Batallon("batallon" + i, bando, posx, posy, 0, map);
            for (int j = 0; j < 9; j++) {
                int cant = sc.nextInt();
                for (int k = 0; k < cant; k++) {
                    switch (j) {
                        case 0:
                            bat.agregarPersonaje(new Heroe());
                            break;
                        case 1:
                            bat.agregarPersonaje(new Rabona());
                            break;
                        case 2:
                            bat.agregarPersonaje(new ArtilleriaRealista());
                            break;
                        case 3:
                            bat.agregarPersonaje(new MeleePeru());
                            break;
                        case 4:
                            bat.agregarPersonaje(new RangoPeru());
                            break;
                        case 5:
                            bat.agregarPersonaje(new MeleeRealista());
                            break;
                        case 6:
                            bat.agregarPersonaje(new RangoRealista());
                            break;
                        case 7:
                            bat.agregarPersonaje(new EspecialMeleeRealista());
                            break;
                        case 8:
                            bat.agregarPersonaje(new EspecialRangoRealista());
                            break;
                    }
                }
            }
            bat.setSprite(map);

            //se setea el sprite segun el mas fuerte

            if (bando == 0) {
                patriotas.agregar_batallon(bat);
            } else {
                if (bando == 1) {
                    realistas.agregar_batallon(bat);
                } else {
                    others.agregar_batallon(bat);
                }
            }
            ejercitos.add(patriotas);
            ejercitos.add(realistas);
            ejercitos.add(others);
        }
    }

    public GestorMapas getGestorMapas() {
        return gestorMapas;
    }

    public void setGestorMapas(GestorMapas gestorMapas) {
        this.gestorMapas = gestorMapas;
    }

    public Juego() throws FileNotFoundException {
        v = new Ventana_principal();
        try {
            cargaSprites();
            cargaTiles();
        } catch (IOException ex) {
            Logger.getLogger(Juego.class.getName()).log(Level.SEVERE, null, ex);
        }
        gestorMapas = new GestorMapas();
        gestorMapas.agrega_mapas("mapa.txt", "La Toma de Cuzco", tiles);
        //se crea la armeria
        arm = new Armeria("armeria.txt");
        cargarEjercitos(ejercitos);
        cargarAldeas();

        this.dib = new Dibujador(25, 9, ejercitos.get(0).getBatallonActivo());
        dib.setVentana(v);
        Scanner sc = new Scanner(System.in);
        this.map = gestorMapas.getmapa("La Toma de Cuzco");
        this.objetivos = new ArrayList();
        seteo_objetivos();
        this.ia = new QuickIA(map, ejercitos.get(1), ejercitos.get(0));
        QuickIA intel = (QuickIA) this.ia;
        intel.setDaemon(true);
        this.ia.set_batobj(this.objetivos.get(0).get_bat_muer());
    }

    public void setArm(Armeria arm) {
        this.arm = arm;
    }

    public void seteo_objetivos() {
        objetivos = new ArrayList();
        Mapa map = gestorMapas.getmapa("La Toma de Cuzco");
        Objetivo obj = new Objetivo(this.tiles);

        //Seteo de objetivo 1:
        Batallon[] arr_matar1 = new Batallon[2];
        arr_matar1[0] = ejercitos.get(1).getBatallones().get(0);
        arr_matar1[1] = ejercitos.get(1).getBatallones().get(1);
        Objetivo obj1 = new Objetivo(true, false, false, arr_matar1, 0, 0, 0, null, 129, 50, 49, map, null, "Objetivo 1: Atencion! hay dos batallones realistas apostados cerca de aqui; es hora de comenzar la accion \n Matalos para seguir avanzando \n");
        //Seteo de objetivo 2:
        Batallon[] arr_reclutar1 = new Batallon[2];
        arr_reclutar1[0] = ejercitos.get(2).getBatallones().get(0);
        arr_reclutar1[1] = ejercitos.get(2).getBatallones().get(1);
        Batallon[] arr_matar2 = new Batallon[2];
        arr_matar2[0] = ejercitos.get(1).getBatallones().get(2);
        arr_matar2[1] = ejercitos.get(1).getBatallones().get(3);
        Objetivo obj2 = new Objetivo(true, false, true, arr_matar2, 0, 0, 0, arr_reclutar1, 109, 50, 49, map, null, "Objetivo 2: Mirad! hay varios grupos nativos en esos edificios, derrota a esos realistas y reclutalos,\n ellos se te uniran\n");
        //Seteo de objetivo 3:
        Batallon[] arr_matar3 = new Batallon[1];
        arr_matar3[0] = ejercitos.get(1).getBatallones().get(4);
        Objetivo obj3 = new Objetivo(true, false, false, arr_matar3, 0, 0, 0, null, 96, 50, 49, map, null, "Objetivo 3: Un ultimo batallon te espera ahí. Golpea fuerte y seguro\nAcabalos de una buena vez\n");
        //Seteo de objetivo 4:
        Batallon[] arr_reclutar2 = new Batallon[1];
        arr_reclutar2[0] = ejercitos.get(2).getBatallones().get(2);
        Objetivo obj4 = new Objetivo(false, false, true, null, 0, 0, 0, arr_reclutar2, 87, 50, 49, map, null, "Objetivo 4: Hay un nativo cerca de aqui, parece que tiene informacion importante \n Reclutale para saber que informacion posee\n");
        //Seteo de objetivo 5:
        Batallon[] arr_matar4 = new Batallon[3];
        arr_matar4[0] = ejercitos.get(1).getBatallones().get(5);
        arr_matar4[1] = ejercitos.get(1).getBatallones().get(6);
        arr_matar4[2] = ejercitos.get(1).getBatallones().get(7);
        Objetivo obj5 = new Objetivo(true, false, false, arr_matar4, 0, 0, 0, null, 76, 50, 49, map, null, "Objetivo 5: ¡Cuidado! Hay muchos fusileros en los techos, acaba a todos los realistas\n Seria un peligro dejarlos vivos\n");
        //Seteo de objetivo 6:
        Objetivo obj6 = new Objetivo(false, true, false, null, 76, 50, 49, null, 74, 50, 49, map, ejercitos.get(0), "Objetivo 6: Avanza");
        //Seteo de objetivo 7:
        Batallon[] arr_mataresp = new Batallon[12];
        arr_mataresp[0] = ejercitos.get(1).getBatallones().get(8);
        arr_mataresp[1] = ejercitos.get(1).getBatallones().get(9);
        arr_mataresp[2] = ejercitos.get(1).getBatallones().get(10);
        arr_mataresp[3] = ejercitos.get(1).getBatallones().get(11);
        arr_mataresp[4] = ejercitos.get(1).getBatallones().get(12);
        arr_mataresp[5] = ejercitos.get(1).getBatallones().get(13);
        arr_mataresp[6] = ejercitos.get(1).getBatallones().get(14);
        arr_mataresp[7] = ejercitos.get(1).getBatallones().get(15);
        arr_mataresp[8] = ejercitos.get(1).getBatallones().get(16);
        arr_mataresp[9] = ejercitos.get(1).getBatallones().get(17);
        arr_mataresp[10] = ejercitos.get(1).getBatallones().get(18);
        arr_mataresp[11] = ejercitos.get(1).getBatallones().get(19);

        Objetivo obj7 = new Objetivo(false, true, false, arr_mataresp, 10, 56, 44, null, 9, 55, 44, map, ejercitos.get(0), "Objetivo 7: ¡Bien! Ahora eres sufcientemente fuerte, llega hasta la municipalidad.\nPuedes reclutar mas nativos y seguir obteniendo poderosas armas de los realistas.\n Las necesitaras por la batalla final\n\n");
        //Seteo de objetivo 8:
        Batallon[] arr_matar5 = new Batallon[2];
        arr_matar5[0] = ejercitos.get(1).getBatallones().get(20);
        arr_matar5[1] = ejercitos.get(1).getBatallones().get(21);
        Objetivo obj8 = new Objetivo(true, false, false, arr_matar5, 0, 0, 0, null, 7, 50, 49, map, null, "Objetivo 8: ¡Llega al alcalde! acaba con los realistas\n");
        //Seteo de objetivo 9:
        Batallon[] arr_matar6 = new Batallon[2];
        arr_matar6[0] = ejercitos.get(1).getBatallones().get(22);
        arr_matar6[1] = ejercitos.get(1).getBatallones().get(23);
        Objetivo obj9 = new Objetivo(true, false, false, arr_matar6, 0, 0, 0, null, 5, 50, 49, map, null, "Objetivo 9: Ya casi cumples tu cometido, acaba con estos ultimos realistas\n");
        //Seteo de objetivo 10:
        Batallon[] arr_matar7 = new Batallon[1];
        arr_matar7[0] = ejercitos.get(1).getBatallones().get(24);
        Objetivo obj10 = new Objetivo(true, false, false, arr_matar6, 0, 0, 0, null, 1, 50, 49, map, null, "Objetivo 10: ¿Aun quiere defenderse? Termina tu mision y has sentir a los españoles que los peruanos somos un pueblo libre\n Finiquita al alcalde\n");

        objetivos.add(obj1);
        objetivos.add(obj2);
        objetivos.add(obj3);
        objetivos.add(obj4);
        objetivos.add(obj5);
        objetivos.add(obj6);
        objetivos.add(obj7);
        objetivos.add(obj8);
        objetivos.add(obj9);
        objetivos.add(obj10);
    }

    public void impresiones_objetivos() {

        for (int i = 0; i < objetivos.size(); i++) {

            if (!objetivos.get(i).is_cumplido()) {

                objetivos.get(i).imprime_objetivo(v);
                return;
            }
        }
    }

    public int revisaAldea(Batallon bat) {
        int num = aldeas.size();
        int x, y, a, b;


        for (int i = 0; i < num; i++) {
            x = aldeas.get(i).getX();
            y = aldeas.get(i).getY();
            a = aldeas.get(i).getA();
            b = aldeas.get(i).getB();
            if (bat.getX() <= x + a + 1 && bat.getX() >= x - a - 1 && bat.getY() <= y + b + 1 && bat.getY() >= y - b - 1) {
                return i;
            }
        }
        return -1;
    }

    public void jugar() throws FileNotFoundException, IOException {

        ejercitos.get(0).set_hilo((QuickIA) ia);
        ejercitos.get(1).set_hilo((QuickIA) ia);
        ejercitos.get(2).set_hilo((QuickIA) ia);
        v.setDibujador(dib);
        v.setEjercitos(ejercitos);
        v.setMapa(map);
        v.setObjetivos(objetivos);
        v.setIA(ia);
        v.setAldeas(aldeas);
        v.setJuego(this);
        Batallon bat = ejercitos.get(0).getBatallones().get(0);
        v.setMostrarMenu(true);
        dib.dibuja(map);
        bat.setActivo(true);
        dib.setBatallonActivo(bat);
        v.setImprimirObj(true);
        v.impresiones_objetivos();
//        v.update(v.getGraphics()); 
        v.dibuja();
        ((QuickIA) ia).v = v;
        ((QuickIA) ia).start();
        v.creaComprobadores();
    }

    public void jugar2(Batallon bat) throws FileNotFoundException, IOException {
        ejercitos.get(0).set_hilo((QuickIA) ia);
        ejercitos.get(1).set_hilo((QuickIA) ia);
        ejercitos.get(2).set_hilo((QuickIA) ia);
        v.setDibujador(dib);
        v.setEjercitos(ejercitos);
        v.setMapa(map);
        v.setObjetivos(objetivos);
        v.setIA(ia);

        v.setAldeas(aldeas);
        v.setJuego(this);
        //Batallon bat = ejercitos.get(0).getBatallones().get(0);
        v.setMostrarMenu(true);
        dib.dibuja(map);
        //bat.setActivo(true);
        dib.setBatallonActivo(bat);
        v.setImprimirObj(true);
        v.impresiones_objetivos();
//        v.update(v.getGraphics());
        v.dibuja();
        ((QuickIA) ia).v = v;
        ((QuickIA) ia).start();
        v.creaComprobadores();
    }

    public static void guardar_juego(Juego j) //throws IOException
    {
        String ruta;
        int returnVal;
        JFileChooser chooser = new JFileChooser("./");
        FileNameExtensionFilter filter = new FileNameExtensionFilter("Archivos de grabado SAV", "sav");
        chooser.setDialogType(JFileChooser.SAVE_DIALOG);
        chooser.setFileFilter(filter);
        returnVal = chooser.showSaveDialog(chooser);
        if (returnVal == JFileChooser.APPROVE_OPTION) {
            ruta = chooser.getSelectedFile().getPath();
            if (!ruta.contains(".sav")) {
                ruta += ".sav";
            }
            try {
                ObjectOutputStream escritor = new ObjectOutputStream(new BufferedOutputStream(new FileOutputStream(ruta)));
//                JOptionPane.showMessageDialog(null, "se creo");
                //JOptionPane.showMessageDialog(null,ruta);
                escritor.writeObject(j);
                escritor.close();
                JOptionPane.showMessageDialog(null, "Juego guardado exitosamente");
            } catch (IOException e) {
                JOptionPane.showMessageDialog(null, e.getMessage());
            }

        }
    }

    public void recargarAldeas() {
        for (int i = 0; i < aldeas.size(); i++) {
            if (!aldeas.get(i).isVacia()) {
                aldeas.get(i).seteaSprite(map);
            }
        }
    }
}
